package com.wanfajie.smsdistribute.common.adapter

import android.content.Context
import android.support.annotation.CallSuper
import android.support.v7.widget.PopupMenu
import android.support.v7.widget.RecyclerView
import android.view.*

abstract class EditableRecyclerAdapter<E>(
        private val ctx: Context,
        private val layoutId: Int,
        private val menuId: Int,
        data: Collection<E>,
        private val anchorId: Int = 0
): RecyclerView.Adapter<RecyclerViewHolder>() {

    private val dataList: MutableList<E> by lazy {
        RecyclerAdapterLinkedList<E, RecyclerViewHolder>(this, data)
    }

    private val inflater = LayoutInflater.from(ctx)
    private var mRecyclerView: RecyclerView? = null

    private var onItemClick: ((E) -> Unit)? = null

    final override fun onCreateViewHolder(p0: ViewGroup, p1: Int): RecyclerViewHolder {
        val view = inflater.inflate(layoutId, p0, false)
        return RecyclerViewHolder(view)
    }

    private fun getItem(index: Int): E {
        return dataList[index]
    }

    override fun onBindViewHolder(p0: RecyclerViewHolder, p1: Int) {
        if (p0.view.tag == null) {
            p0.view.setOnLongClickListener { it ->
                val vh = it.tag as RecyclerViewHolder
                val anchor = if (anchorId == 0) it else vh.get(anchorId)

                PopupMenu(ctx, anchor).apply {
                    val item: E = vh.tag as E
                    onCreatePopupMenu(menuInflater, menu, item)
                    setOnMenuItemClickListener {
                        onMenuItemClick(it, item)
                    }
                }.show()

                true
            }

            p0.view.setOnClickListener {
                val vh = it.tag as RecyclerViewHolder
                val item: E = vh.tag as E
                onItemClick?.invoke(item)
            }

            p0.view.tag = p0
        }

        p0.tag = getItem(p1)
        onRenderView(p0, getItem(p1))
    }

    override fun getItemId(position: Int): Long {
        return dataList[position].hashCode().toLong() shl 4 or position.toLong()
    }

    override fun getItemCount(): Int {
        return dataList.size
    }

    abstract fun onRenderView(viewHolder: RecyclerViewHolder, item: E)

    open fun onMenuItemClick(menuItem: MenuItem, item: E): Boolean = true

    @CallSuper
    open fun onCreatePopupMenu(inflater: MenuInflater, menu: Menu, item: E) {
        inflater.inflate(menuId, menu)
    }

    fun setOnItemClickListener(listener: ((E) -> Unit)?) {
        onItemClick = listener
    }

    fun indexOf(item: E): Int {
        return dataList.indexOf(item)
    }

    fun removeItem(item: E) {
        dataList.remove(item)
    }

    fun addItem(pos: Int, item: E) {
        dataList.add(pos, item)
        mRecyclerView?.scrollToPosition(pos)
    }

    fun appendItem(item: E) {
        dataList.add(item)
        mRecyclerView?.scrollToPosition(itemCount-1)
    }

    fun setData(newData: List<E>) {
        dataList.clear()
        dataList.addAll(newData)
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
        mRecyclerView = recyclerView
    }

    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
        super.onDetachedFromRecyclerView(recyclerView)
        mRecyclerView = null
    }
}
